package com.xu.tasks;


import com.alibaba.fastjson.JSON;
import com.xu.pojo.Movie;
import com.xu.pojo.MovieDetail;
import com.xu.service.MovieService;
import com.xu.tasks.observer.MovieDetailObserver;
import com.xu.uitls.DateUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;
import us.codecraft.webmagic.scheduler.QueueScheduler;
import us.codecraft.webmagic.selector.Selectable;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Component
public class MoviePageProcessor implements PageProcessor {
    @Autowired
    private MovieService movieService;
    @Autowired
    private MovieDetailObserver movieDetailObserver;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    private String url = "http://maoyan.com/?requestCode=0439e623f5c0eb9ee12cc23ef6d2957elzoju";
    private String detailUrl = "http://maoyan.com";
    private Site site = Site.me()
            .setCharset("utf-8") //设置编码
            .setCycleRetryTimes(3000) //设置重试时间间隔
            .setTimeOut(10000) //超时时间
            .addCookie("__mta","48520601.1607779369251.1620381750409.1620381813865.87")
            .addCookie("_lxsdk_cuid","176571e40e6c8-011fb5ea0a6c44-5a301e42-1fa400-176571e40e6c8")
            .addCookie("uuid_n_v","v1")
            .addCookie("uuid","7C1491C0992311EBA7B82542C746DAD72C6A5358FBC64EAB91570C7B46FF06DB")
            .addCookie("_csrf","a40392e61503dca20c3b26633fb462d2c75b3a9bab580f4d1ce90c93d0f22f95")
            .addCookie("Hm_lvt_703e94591e87be68cc8da0da7cbd0be2","1617966326,1620364847,1620381746")
            .addCookie("_lx_utm","utm_source%3DBaidu%26utm_medium%3Dorganic")
            .addCookie("__mta","48520601.1607779369251.1620381747256.1620381756491.90")
            .addCookie("Hm_lpvt_703e94591e87be68cc8da0da7cbd0be2","1620381814")
            .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.51")
            .setSleepTime(3); //设置重试次数

    @SneakyThrows
    @Override
    public void process(Page page) {
        List<Selectable> nodes = page.getHtml().css("div.movie-grid div.panel").nodes();

        if (redisTemplate.opsForList().range("movies",0,-1).size() > 0) {
            redisTemplate.delete("movies");
        }
        for (Selectable node : nodes) {
            if (node.css("span.panel-title h2","text").toString().substring(0,4).equals("正在热映")){
                List<Selectable> hots = node.css("div.panel-content dd").nodes();
                for (Selectable hot : hots) {
                    //System.out.println(hot);
                    String name = hot.css("div.movie-title", "text").toString();
                    String img = hot.css("img.movie-poster-img", "data-src").toString();

                    Double score = null;
                    if (hot.css("i.integer","text").toString() != null && hot.css("i.fraction","text").toString() != null){
                        score = Double.parseDouble(hot.css("i.integer","text").toString() + hot.css("i.fraction","text").toString());
                    }

                    String state = "正在热映";
                    String updateTime = DateUtil.gainTime(new Date());
                    Movie movie = new Movie(null, name, img, score, state, updateTime, new MovieDetail());

                    //持久化
                    movieService.saveMovie(movie);
                    //System.out.println(movie);

                    if (movie.getId() != null){
                        movie.getMovieDetail().setMovieId(movie.getId());
                        String url = detailUrl + hot.css("a","href").toString();
                        MovieDetailPageProcessor movieDetailPageProcessor = new MovieDetailPageProcessor();
                        movieDetailPageProcessor.setUrl(url);
                        movieDetailPageProcessor.setMovieDetail(movie.getMovieDetail());
                        movieDetailObserver.addMovieDetailPageProcessor(movieDetailPageProcessor);
                    }
                }
            } else if (node.css("span.panel-title h2","text").toString().substring(0,4).equals("即将上映")){
                List<Selectable> comings = node.css("div.panel-content dd").nodes();
                for (Selectable coming : comings) {
                    //System.out.println(coming);
                    String name = coming.css("div.movie-title", "text").toString();
                    String img = coming.css("img.movie-poster-img", "data-src").toString();

                    Double score = null;
                    if (coming.css("i.integer","text").toString() != null && coming.css("i.fraction","text").toString() != null){
                        score = Double.parseDouble(coming.css("i.integer","text").toString() + coming.css("i.fraction","text").toString());
                    }

                    String state = "即将上映";
                    String updateTime = DateUtil.gainTime(new Date());
                    Movie movie = new Movie(null, name, img, score, state, updateTime, new MovieDetail());

                    //持久化
                    movieService.saveMovie(movie);
                    //System.out.println(movie);

                    if (movie.getId() != null){
                        movie.getMovieDetail().setMovieId(movie.getId());
                        String url = detailUrl + coming.css("a","href").toString();
                        MovieDetailPageProcessor movieDetailPageProcessor = new MovieDetailPageProcessor();
                        movieDetailPageProcessor.setUrl(url);
                        movieDetailPageProcessor.setMovieDetail(movie.getMovieDetail());
                        movieDetailObserver.addMovieDetailPageProcessor(movieDetailPageProcessor);
                    }
                }
            }
        }

        redisTemplate.expire("movies",50,TimeUnit.MINUTES);
        while (movieDetailObserver.getMovieDetailPageProcessorSet().size() > 0){
            movieDetailObserver.doNotify();

            if (movieDetailObserver.getMovieDetailPageProcessorSet().size() > 0)
                TimeUnit.MINUTES.sleep(1);
        }
    }


    @Override
    public Site getSite() {
        return site;
    }


    @Scheduled(initialDelay = 10, fixedDelay = 1000 * 60 * 60)
    public void exec(){
        Spider.create(this)
                .addUrl(url)
                .thread(5)
                .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(1000)))
                .run();
    }
}
